package cc.siyecao.mapper.conditions;

import cc.siyecao.mapper.common.util.StringUtils;

import java.io.Serializable;
import java.util.Collection;

public interface StringCompare<W> extends Serializable {
    /**
     * 等于 =
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W eq(String column, Object val) {
        return eq( true, column, val );
    }

    /**
     * 等于 =
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    W eq(boolean condition, String column, Object val);

    /**
     * 等于 =
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W eqIfPresent(String column, Object val) {
        return eq( StringUtils.checkValNotNull( val ), column, val );
    }

    /**
     * 不等于 &lt;&gt;
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W ne(String column, Object val) {
        return ne( true, column, val );
    }

    /**
     * 不等于 &lt;&gt;
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W neIfPresent(String column, Object val) {
        return ne( StringUtils.checkValNotNull( val ), column, val );
    }


    /**
     * 不等于 &lt;&gt;
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    W ne(boolean condition, String column, Object val);

    /**
     * 大于 &gt;
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W gt(String column, Object val) {
        return gt( true, column, val );
    }

    /**
     * 大于 &gt;
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W gtIfPresent(String column, Object val) {
        return gt( StringUtils.checkValNotNull( val ), column, val );
    }

    /**
     * 大于 &gt;
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    W gt(boolean condition, String column, Object val);

    /**
     * 大于等于 &gt;=
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W ge(String column, Object val) {
        return ge( true, column, val );
    }

    /**
     * 大于等于 &gt;=
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W geIfPresent(String column, Object val) {
        return ge( StringUtils.checkValNotNull( val ), column, val );
    }

    /**
     * 大于等于 &gt;=
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    W ge(boolean condition, String column, Object val);

    /**
     * 小于 &lt;
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W lt(String column, Object val) {
        return lt( true, column, val );
    }

    /**
     * 小于 &lt;
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W ltIfPresent(String column, Object val) {
        return lt( StringUtils.checkValNotNull( val ), column, val );
    }

    /**
     * 小于 &lt;
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    W lt(boolean condition, String column, Object val);

    /**
     * 小于等于 &lt;=
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W le(String column, Object val) {
        return le( true, column, val );
    }

    /**
     * 小于等于 &lt;=
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W leIfPresent(String column, Object val) {
        return le( StringUtils.checkValNotNull( val ), column, val );
    }

    /**
     * 小于等于 &lt;=
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    W le(boolean condition, String column, Object val);

    /**
     * BETWEEN 值1 AND 值2
     *
     * @param column 字段
     * @param val1   值1
     * @param val2   值2
     * @return children
     */
    default W between(String column, Object val1, Object val2) {
        return between( true, column, val1, val2 );
    }

    /**
     * BETWEEN 值1 AND 值2
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param val1      值1
     * @param val2      值2
     * @return children
     */
    W between(boolean condition, String column, Object val1, Object val2);

    /**
     * NOT BETWEEN 值1 AND 值2
     *
     * @param column 字段
     * @param val1   值1
     * @param val2   值2
     * @return children
     */
    default W notBetween(String column, Object val1, Object val2) {
        return notBetween( true, column, val1, val2 );
    }

    /**
     * NOT BETWEEN 值1 AND 值2
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param val1      值1
     * @param val2      值2
     * @return children
     */
    W notBetween(boolean condition, String column, Object val1, Object val2);

    /**
     * LIKE '%值%'
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W like(String column, Object val) {
        return like( true, column, val );
    }

    /**
     * LIKE '%值%'
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W likeIfPresent(String column, Object val) {
        return like( StringUtils.checkValNotNull( val ), column, val );
    }

    /**
     * LIKE '%值%'
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    W like(boolean condition, String column, Object val);

    /**
     * NOT LIKE '%值%'
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W notLike(String column, Object val) {
        return notLike( true, column, val );
    }

    /**
     * NOT LIKE '%值%'
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W notLikeIfPresent(String column, Object val) {
        return notLike( StringUtils.checkValNotNull( val ), column, val );
    }

    /**
     * NOT LIKE '%值%'
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    W notLike(boolean condition, String column, Object val);

    /**
     * NOT LIKE '%值'
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W notLikeLeft(String column, Object val) {
        return notLikeLeft( true, column, val );
    }

    /**
     * NOT LIKE '%值'
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W notLikeLeftIfPresent(String column, Object val) {
        return notLikeLeft( StringUtils.checkValNotNull( val ), column, val );
    }

    /**
     * NOT LIKE '%值'
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    W notLikeLeft(boolean condition, String column, Object val);

    /**
     * NOT LIKE '值%'
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W notLikeRight(String column, Object val) {
        return notLikeRight( true, column, val );
    }

    /**
     * NOT LIKE '值%'
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W notLikeRightIfPresent(String column, Object val) {
        return notLikeRight( StringUtils.checkValNotNull( val ), column, val );
    }

    /**
     * NOT LIKE '值%'
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    W notLikeRight(boolean condition, String column, Object val);

    /**
     * LIKE '%值'
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W likeLeft(String column, Object val) {
        return likeLeft( true, column, val );
    }

    /**
     * LIKE '%值'
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W likeLeftIfPresent(String column, Object val) {
        return likeLeft( StringUtils.checkValNotNull( val ), column, val );
    }

    /**
     * LIKE '%值'
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    W likeLeft(boolean condition, String column, Object val);

    /**
     * LIKE '值%'
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W likeRight(String column, Object val) {
        return likeRight( true, column, val );
    }

    /**
     * LIKE '值%'
     *
     * @param column 字段
     * @param val    值
     * @return children
     */
    default W likeRightIfPresent(String column, Object val) {
        return likeRight( StringUtils.checkValNotNull( val ), column, val );
    }

    /**
     * LIKE '值%'
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param val       值
     * @return children
     */
    W likeRight(boolean condition, String column, Object val);

    /**
     * 字段 IS NULL
     * <p>例: isNull("name")</p>
     *
     * @param column 字段
     * @return children
     */
    default W isNull(String column) {
        return isNull( true, column );
    }

    /**
     * 字段 IS NULL
     * <p>例: isNull("name")</p>
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @return children
     */
    W isNull(boolean condition, String column);

    /**
     * 字段 IS NOT NULL
     * <p>例: isNotNull("name")</p>
     *
     * @param column 字段
     * @return children
     */
    default W isNotNull(String column) {
        return isNotNull( true, column );
    }

    /**
     * 字段 IS NOT NULL
     * <p>例: isNotNull("name")</p>
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @return children
     */
    W isNotNull(boolean condition, String column);

    /**
     * 字段 IN (value.get(0), value.get(1), ...)
     * <p>例: in("id", Arrays.asList(1, 2, 3, 4, 5))</p>
     *
     * <li> 注意！集合为空若存在逻辑错误，请在 condition 条件中判断 </li>
     * <li> 如果集合为 empty 则不会进行 sql 拼接 </li>
     *
     * @param column 字段
     * @param coll   数据集合
     * @return children
     */
    default W in(String column, Collection<?> coll) {
        return in( true, column, coll );
    }

    /**
     * 字段 IN (value.get(0), value.get(1), ...)
     * <p>例: in("id", Arrays.asList(1, 2, 3, 4, 5))</p>
     *
     * @param column 字段
     * @param coll   值
     * @return children
     */
    default W inIfPresent(String column, Collection<?> coll) {
        return in( StringUtils.isNotEmpty( coll ), column, coll );
    }

    /**
     * 字段 IN (value.get(0), value.get(1), ...)
     * <p>例: in("id", Arrays.asList(1, 2, 3, 4, 5))</p>
     *
     * <li> 注意！集合为空若存在逻辑错误，请在 condition 条件中判断 </li>
     * <li> 如果集合为 empty 则不会进行 sql 拼接 </li>
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param coll      数据集合
     * @return children
     */
    W in(boolean condition, String column, Collection<?> coll);

    /**
     * 字段 IN (v0, v1, ...)
     * <p>例: in("id", 1, 2, 3, 4, 5)</p>
     *
     * <li> 注意！数组为空若存在逻辑错误，请在 condition 条件中判断 </li>
     * <li> 如果动态数组为 empty 则不会进行 sql 拼接 </li>
     *
     * @param column 字段
     * @param values 数据数组
     * @return children
     */
    default W in(String column, Object... values) {
        return in( true, column, values );
    }

    /**
     * 字段 IN (v0, v1, ...)
     * <p>例: in("id", 1, 2, 3, 4, 5)</p>
     *
     * @param column 字段
     * @param values 值
     * @return children
     */
    default W inIfPresent(String column, Object... values) {
        return in( StringUtils.isNotEmpty( values ), column, values );
    }

    /**
     * 字段 IN (v0, v1, ...)
     * <p>例: in("id", 1, 2, 3, 4, 5)</p>
     *
     * <li> 注意！数组为空若存在逻辑错误，请在 condition 条件中判断 </li>
     * <li> 如果动态数组为 empty 则不会进行 sql 拼接 </li>
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param values    数据数组
     * @return children
     */
    W in(boolean condition, String column, Object... values);

    /**
     * 字段 NOT IN (value.get(0), value.get(1), ...)
     * <p>例: notIn("id", Arrays.asList(1, 2, 3, 4, 5))</p>
     *
     * @param column 字段
     * @param coll   数据集合
     * @return children
     */
    default W notIn(String column, Collection<?> coll) {
        return notIn( true, column, coll );
    }

    /**
     * 字段 NOT IN (value.get(0), value.get(1), ...)
     * <p>例: notIn("id", Arrays.asList(1, 2, 3, 4, 5))</p>
     *
     * @param column 字段
     * @param coll   值
     * @return children
     */
    default W notInIfPresent(String column, Collection<?> coll) {
        return notIn( StringUtils.isNotEmpty( coll ), column, coll );
    }

    /**
     * 字段 NOT IN (value.get(0), value.get(1), ...)
     * <p>例: notIn("id", Arrays.asList(1, 2, 3, 4, 5))</p>
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param coll      数据集合
     * @return children
     */
    W notIn(boolean condition, String column, Collection<?> coll);

    /**
     * 字段 NOT IN (v0, v1, ...)
     * <p>例: notIn("id", 1, 2, 3, 4, 5)</p>
     *
     * @param column 字段
     * @param values 数据数组
     * @return children
     */
    default W notIn(String column, Object... values) {
        return notIn( true, column, values );
    }

    /**
     * 字段 NOT IN (v0, v1, ...)
     * <p>例: notIn("id", 1, 2, 3, 4, 5)</p>
     *
     * @param column 字段
     * @param values 值
     * @return children
     */
    default W notInIfPresent(String column, Object... values) {
        return notIn( StringUtils.isNotEmpty( values ), column, values );
    }

    /**
     * 字段 NOT IN (v0, v1, ...)
     * <p>例: notIn("id", 1, 2, 3, 4, 5)</p>
     *
     * @param condition true：执行条件  false：忽略条件
     * @param column    字段
     * @param values    数据数组
     * @return children
     */
    W notIn(boolean condition, String column, Object... values);

}
